/******************************************************************************
 * Copyright (C), 2014, BeeIoT Tech. Co., Ltd. 
 * FileName:        pdu_handle.c
 * Author:          lvxin 
 * Version :        1.0
 * Date:            2014-12-23 15:48:53
 * Description:
 * Function List:   1. -------
 * History:
 * <author>     <time>                <version >  <desc> 
 * lvxin        2014-12-23 15:48:53   1.0         build this moudle 
 *****************************************************************************/

/******************************************************************************
 *  *INCLUDES
 *  */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "pdu.h"
#include "object.h"
#include "option.h"

#ifndef INNER_DEBUG
#include "smset.h"
#endif

/******************************************************************************
 *  *EXTERNAL FUNCTION
 *  */
extern int pdu_err_fifo_push (int errcode);
extern int pdu_err_fifo_pop(void);

/******************************************************************************
 *  *MICROS
 *  */
#define     DIM(x)  (sizeof(x)/sizeof(x[0]))

/******************************************************************************
 *  *FUNCTION DECLARES
 *  */
static int pdu_spt_is_string_num(char *msg, int len);
static int _handle_set_dp_num   (char *data, int len);
static int _handle_set_dp_temp  (char *data, int len);
static int _handle_set_dp_hum   (char *data, int len);
static int _handle_set_dp_time  (char *data, int len);
/*static int __handle_set_tel      (char *data, int len);*/
static int _handle_query_dp     (char *data, int len);
/*static int __handle_query_tel    (char *data, int len);*/

/******************************************************************************
 *  *LOCAL VARIABLES
 *  */

static pdu_option_params_t l_option_params;   //保存系统设置参数
static option_t *l_option;

/******************************************************************************
 *  *CONSTANTS
 *  */
//注意：key值需要交换高低8位
static const pdu_key_handle_t key_set_handle_array[]=
{
    {"设置",      _handle_set_dp_num    }, //匹配"设置"
    {"温度",      _handle_set_dp_temp}, //匹配"温度"
    {"湿度",      _handle_set_dp_hum }, //匹配"温度"
    {"时间",      _handle_set_dp_time}, //匹配"时间"
};

static const pdu_key_handle_t key_query_handle_array[]=
{
    {"查询",  _handle_query_dp    }, //匹配"设置查询"
};

static const char *l_error_info[]={
    "参数错误\n",   //PDU_PARSE_PARAMS, //参数错误       
    "数据格式错误\n",   //PDU_PARSE_FORMAT, //数据格式错误   
    "时间格式错误\n",   //PDU_PARSE_TIME, //时间格式错误     
    "手机号码错误\n",   //PDU_PARSE_TELERROR, //手机号码错误 
    "未知错误\n",   //PDU_PARSE_UNKNOWN, //未知错误      
    "设置大棚参数需要输入大棚号！\n",//PDU_PARSE_NO_DPNUM
    "温度参数输入错误\n", //PDU_PARSE_TEMP_PARAMS
    "湿度参数输入错误\n", //PDU_PARSE_HUM_PARAMS
    "设置大棚参数需要输入参数！\n",//PDU_PARSE_NO_PARAM
};



/******************************************************************************
 *  *PUBLIC FUNCTIONS
 *  */

//注意！此函数被PDU.C中pdu_decode()函数所调用，名称不可修改
void pdu_handle_init(const pdu_key_handle_t **handle_arr, int *handle_num
        ,char cmd_type)
{
    switch (cmd_type)
    {
        case 0 :
            *handle_arr = key_set_handle_array;
            *handle_num = DIM(key_set_handle_array);
            l_option_params.humd[0] = -1;
            l_option_params.humd[1] = -1;
            l_option_params.temp[0] = -1;
            l_option_params.temp[1] = -1;
            l_option_params.num = -1;
            l_option_params.time.start_time = 0xffff;
            l_option_params.time.stop_time = 0xffff;
            l_option_params.save_option_flag = 0;
            memset (l_option_params.telnum, 0, 12);
            break;
        case 1 :
            *handle_arr = key_query_handle_array;
            *handle_num = DIM(key_query_handle_array);
            break;
        default :
            break;
    }
}

//注意！此函数被PDU.C中pdu_parse_field_proc()函数所调用，定义不可修改
/******************************************************************************
 * Function:        pdu_error_handle()
 * Description:     处理错误信息
 * Calls:            
 * Called By:        
 * Input:            
 * Return:           
 * Others:              
 *****************************************************************************/
int pdu_error_handle(int info)
{
    if (info < PDU_PARSE_ENUM_MAX)
        pdu_err_fifo_push (info);
    return 0;
}

//解析到最后执行
int pdu_final(void)
{

    DBG_PRINTF("**执行结束**");
    sm_inner_cmd_push_fifo (CMD_FLUSH_SMS, 0);
    return 0;
}

/******************************************************************************
 * Function:        pdu_save_options()
 * Description:     保存设置参数
 * Calls:            
 * Called By:       pdu_parse()函数
 * Input:           void
 * Return:          0 --成功  -1 --失败
 * Others:           
 *****************************************************************************/
int pdu_save_options(int field_total)
{
    if (field_total <= 1 && l_option_params.telnum[0] && strlen(l_option_params.telnum) == 0)
        pdu_err_fifo_push (PDU_PARSE_NO_PARAM);
    sm_inner_cmd_push_fifo (CMD_RES_SETUP_INFO, 0);
    /*sm_inner_cmd_push_fifo (CMD_RES_SETUP_INFO, 0);*/
    return 0;
}

/*******************************************************************************
 * Function:      pdu_spt_is_string_num()
 * Description:   检查字符串是否是纯数字字符串
 * Calls:         
 * Called By:      
 * Input:         msg   --字符串
 * 
 * Return:        0   --是数字字串
 *                -1  --不是纯数字字串，包含其他字符
 * Others:        None
 ******************************************************************************/
static int pdu_spt_is_string_num(char *msg, int len)
{
    int i = 0;
    if (len == 0) return -1;
    for (i = 0 ; i < len; i ++)
    {
        if (msg[i] >= '0' && msg[i] <= '9')
        {
            continue;
        }
        else
        {
            return -1;
        }
    }
    return 0;
}

//执行设置保存
int _pdu_save_options(void)
{
    int dpnum = -1;
    int i;
    if (l_option_params.num == -1 && l_option_params.save_option_flag == 1)
    {
        SMS_printf ("[错误]%s", l_error_info[PDU_PARSE_NO_DPNUM]);
        return -1;
    }
    if (l_option_params.num != -1)
    {
        dpnum = l_option_params.num;
        if (dpnum > l_option->number)
            SMS_printf ("[错误]大棚序号超过现有大棚数\n");

        if (dpnum == 0)
        {
            SMS_printf ("设置所有大棚参数：%d\n");
        }
        else
        {
            SMS_printf ("设置大棚：%d\n", l_option_params.num);
        }

        /*{++++++++++++设置温度报警上下限++++++++++++*/
        if (l_option_params.temp[0] != -1 && l_option_params.temp[0] != -1)
        {
            l_option->dp[dpnum].temperature_low  =  l_option_params.temp[0] * 10;
            l_option->dp[dpnum].temperature_high =  l_option_params.temp[1] * 10;
            if((!l_option->dp[dpnum].temperature_low)&&(!l_option->dp[dpnum].temperature_high))
            {
                l_option->dp[dpnum].temperature_switch = 0;
            }
            else
            {
                l_option->dp[dpnum].temperature_switch = 1;
            }

            if(dpnum == 0) //设置全局参数
            {
                for(i = 1; i <= l_option->number; i++)
                {
                    l_option->dp[i].temperature_low    = l_option->dp[0].temperature_low  ;
                    l_option->dp[i].temperature_high   = l_option->dp[0].temperature_high ;
                    l_option->dp[i].temperature_switch = l_option->dp[0].temperature_switch; 
                }
            }
            SMS_printf ("温度范围: %02d℃-%02d℃",l_option_params.temp[0], l_option_params.temp[1]);
            SMS_printf ("\n");
        }
        /*}------------设置温度报警上下限------------*/

        /*{++++++++++++设置湿度报警上下限++++++++++++*/
        if (l_option_params.humd[0] != -1 && l_option_params.humd[0] != -1)
        {
            l_option->dp[dpnum].humidity_low  =  l_option_params.humd[0] * 10;
            l_option->dp[dpnum].humidity_high =  l_option_params.humd[1] * 10;
            if((!l_option->dp[dpnum].humidity_low)&&(!l_option->dp[dpnum].humidity_high))
            {
                l_option->dp[dpnum].humidity_switch = 0;
            }
            else
            {
                l_option->dp[dpnum].humidity_switch = 1;
            }

            if(dpnum == 0) //设置全局参数
            {
                for(i = 1; i <= l_option->number; i++)
                {
                    l_option->dp[i].humidity_low    = l_option->dp[0].humidity_low ;
                    l_option->dp[i].humidity_high   = l_option->dp[0].humidity_high;
                    l_option->dp[i].humidity_switch = l_option->dp[0].humidity_switch;
                }
            }
            else
            {
            }
            SMS_printf ("湿度范围: %02d％-%02d％",l_option_params.humd[0], l_option_params.humd[1]);
            SMS_printf ("\n");
        }
        /*}------------设置湿度报警上下限------------*/

        /*{++++++++++++设置报警时间++++++++++++*/
        if (l_option_params.time.start_time != 0xFFFF
                &&l_option_params.time.stop_time != 0xFFFF)
        {
            l_option->dp[dpnum].time_start =  l_option_params.time.start_time;
            l_option->dp[dpnum].time_stop  =  l_option_params.time.stop_time;
            if(dpnum == 0) //设置全局参数
            {
                for(i = 1; i <= l_option->number; i++)
                {
                    l_option->dp[i].time_start =  l_option->dp[0].time_start;
                    l_option->dp[i].time_stop  =  l_option->dp[0].time_stop ;
                }
            }
            SMS_printf ("报警起始时间: %02d:%02d\n", 
                    l_option_params.time.start_time >> 8,
                    l_option_params.time.start_time & 0x00ff);
            SMS_printf ("报警结束时间: %02d:%02d\n", 
                    l_option_params.time.stop_time >> 8,
                    l_option_params.time.stop_time & 0x00ff);

        }
        /*}------------设置报警时间------------*/

        SMS_printf ("以上参数设置已保存!\n");
        option_set (l_option);
    }
    //保存手机号
    if (strlen(l_option_params.telnum) != 0)
    {
        for (i = 0; i < 11; i ++)
        {
                 l_option->telephone[0].number[i] = l_option_params.telnum[i] - '0';
        }
        
        option_set (l_option);
        SMS_printf ("成功保存手机号：%s\n", l_option_params.telnum);
    }
    return 0;
}

/******************************************************************************
 *  *LOCAL FUNCTIONS
 *  */

//设置大棚序号
static int _handle_set_dp_num   (char *data, int len)
{
    /*DBG_PRINTF ("[set NU]");*/
    /*fwrite(data, len, 1, stdout);*/
    /*putchar ('\n');*/

    if (len == 0) 
    {
        pdu_error_handle (PDU_PARSE_NO_DPNUM); 
        return 0;
    }
    if(pdu_spt_is_string_num(data, len) == 0)  //检验字符串为数字
    {
        if (pdu_spt_is_string_num(data, len) == 0)
            l_option_params.num = atoi(data);  //设置大棚数据
        else
            pdu_error_handle (PDU_PARSE_NO_DPNUM); 
        /*DBG_PRINTF ("设置大棚：%d\n", atoi(data));*/
    }
    else if (strncmp(data,"手机", len) >= 0)
    {
        if (strlen(data+6) == 11 && pdu_spt_is_string_num(data+6, 11) == 0 && data[6] == '1')
            strncpy (l_option_params.telnum, data+6, 11);
        else
        {
            pdu_err_fifo_push (PDU_PARSE_TELERROR);
        }
        /*pdu_error_handle (PDU_PARSE_PARAMS); //参数错误*/
    }
    else
    {
        pdu_error_handle (PDU_PARSE_NO_DPNUM); 
    }
    return 0;
}

static int __set_dp_data(char *data, int len, int type)
{
    object_t *tmp; //解析字段
    int value1 = 0;
    int value2 = 0;
    char *str1 = NULL;
    char *str2 = NULL;
    tmp = object_string_split (data, '-', NOQUOTES);

    do
    {
        if (object_string_get_field_total(tmp) == 2)
        {
            str1 = object_string_get_field_string(tmp, 1);
            str2 = object_string_get_field_string(tmp, 2);

            if((pdu_spt_is_string_num(str1, strlen(str1)) == 0)  //检验字符串为数字
                    &&(pdu_spt_is_string_num(str2, strlen(str2)) == 0)
              )
            {
                value1 = atoi(str1);
                value2 = atoi(str2);

                if (value1 >= 100 || value2 >= 100) break;
                
                switch (type)
                {
                    case 0 :   //温度上下限
                        l_option_params.temp[0] = (value1 < value2)?value1:value2;
                        l_option_params.temp[1] = (value1 > value2)?value1:value2;
                        break;
                    case 1 :   //湿度上下限
                        l_option_params.humd[0] = (value1 < value2)?value1:value2;
                        l_option_params.humd[1] = (value1 > value2)?value1:value2;
                        break;
                    default :
                        break;
                }
            }
            else
            {
                break;
            }
            object_free (tmp);
            return 0;
        }
    }
    while(0);

    switch (type)
    {
        case 0 :
            pdu_error_handle (PDU_PARSE_TEMP_PARAMS); //温度参数错误
            break;
        case 1 :
            pdu_error_handle (PDU_PARSE_HUM_PARAMS); //湿度度参数错误
            break;
        default :
            break;
    }
    object_free (tmp);
    return 0;
}

static int _handle_set_dp_temp  (char *data, int len)
{
    int ret = __set_dp_data (data, len, 0);
    /*DBG_PRINTF ("设置大棚温度：\n");*/
    /*DBG_PRINTF ("温度上限：%d\n", l_option_params.temp[1]);*/
    /*DBG_PRINTF ("温度下限：%d\n", l_option_params.temp[0]);*/
    return ret;
}

static int _handle_set_dp_hum   (char *data, int len)
{
    int ret = __set_dp_data (data, len, 1);
    /*DBG_PRINTF ("设置大棚湿度：\n");*/
    /*DBG_PRINTF ("湿度上限：%d\n", l_option_params.humd[1]);*/
    /*DBG_PRINTF ("湿度下限：%d\n", l_option_params.humd[0]);*/
    return ret;
}

static int _handle_set_dp_time  (char *data, int len)
{
    object_t *tmp  = NULL; //解析字段
    object_t *time = NULL;  //解析时间
    char *time1 = NULL;
    char *time2 = NULL;
    char *hour = NULL;
    char *minute = NULL;
    uint8_t start_hh = 0;
    uint8_t start_mm = 0;
    uint8_t stop_hh = 0;
    uint8_t stop_mm = 0;
    tmp = object_string_split (data, '-', NOQUOTES);
    do
    {
        if (object_string_get_field_total(tmp) == 2) //拆分两个时间字段
        {
            time1 = object_string_get_field_string(tmp, 1);
            time2 = object_string_get_field_string(tmp, 2);

            //起始时间
            time = object_string_split (time1, ':', NOQUOTES);
            if (object_string_get_field_total(time) == 2) //拆分时间时分字段
            {
                hour = object_string_get_field_string (time, 1);
                minute = object_string_get_field_string (time, 2);
                if((pdu_spt_is_string_num (hour, strlen(hour)) == 0)
                        && (pdu_spt_is_string_num (hour, strlen(hour)) == 0)
                        && (start_hh = atoi(hour)) < 24 
                        && (start_mm = atoi(minute)) < 60)
                {}
                else
                {
                    object_free (time);
                    break;
                }
            }
            else
            {
                object_free (time);
                break;
            }
            object_free (time);

            //结束时间
            time = object_string_split (time2, ':', NOQUOTES);
            if (object_string_get_field_total(time) == 2) //拆分时间时分字段
            {
                hour = object_string_get_field_string (time, 1);
                minute = object_string_get_field_string (time, 2);
                if((pdu_spt_is_string_num (hour, strlen(hour)) == 0)
                        && (pdu_spt_is_string_num (hour, strlen(hour)) == 0)
                        && (stop_hh = atoi(hour)) < 24 
                        && (stop_mm = atoi(minute)) < 60)
                {}
                else
                {
                    object_free (time);
                    break;
                }
            }
            else
            {
                object_free (time);
                break;
            }
            object_free (time);

            /*DBG_PRINTF ("设置大棚时间：%s\n", data);*/
            /*DBG_PRINTF ("起始时间: %d:%d\n", start_hh, start_mm);*/
            /*DBG_PRINTF ("结束时间: %d:%d\n", stop_hh, stop_mm);*/
            l_option_params.time.start_time = start_hh << 8 | start_mm;
            l_option_params.time.stop_time = stop_hh << 8 | stop_mm;
            object_free (tmp);
            return 0;
        }
        else
        {
            break;
        }
    }
    while(0);
    pdu_error_handle (PDU_PARSE_TIME); //时间参数错误
    object_free (tmp);

    return 0;
}

static int _handle_query_dp     (char *data, int len)
{
    int num = -1;
    if (pdu_spt_is_string_num (data, len) == 0)
    {
        num = atoi(data);
#ifndef INNER_DEBUG
        sm_inner_cmd_push_fifo (CMD_QUERY_DP, num);
#endif
        /*DBG_PRINTF ("查询大棚：%d\n", num);*/
    }
    else if (strncmp(data, "手机", strlen("手机")) == 0)
    {
#ifndef INNER_DEBUG
        sm_inner_cmd_push_fifo (CMD_QUERY_TEL, 0);
#endif
        /*DBG_PRINTF ("查询手机号\n");*/
    }
    else
    {
        pdu_error_handle (PDU_PARSE_PARAMS); //参数错误
    }
    return 0;
}


//回复命令执行数据
int pdu_cmd_handle_resp_stat(char cmd, char param)
{
    int tmp;
    /*SMS_printf ("[命令执行结果]\n");*/

    if(_pdu_save_options() != -1)
    {}
    {
        do
        {
            tmp = pdu_err_fifo_pop ();
            if (tmp == -1) break;
            SMS_printf ("[错误]%s",l_error_info[tmp]);
        }while(1);
    }

    return 0;
}

void pdu_option_init(option_t *option)
{
    l_option = option;
}

